package cn.foxtech.device.protocol.v1.iot123.st01;


import cn.foxtech.device.protocol.v1.core.annotation.FoxEdgeDeviceType;
import cn.foxtech.device.protocol.v1.core.annotation.FoxEdgeOperate;
import cn.foxtech.device.protocol.v1.core.exception.ProtocolException;
import cn.foxtech.device.protocol.v1.modbus.core.ModBusProtocol;
import cn.foxtech.device.protocol.v1.modbus.core.ModBusProtocolFactory;
import cn.foxtech.device.protocol.v1.utils.HexUtils;
import cn.foxtech.device.protocol.v1.utils.MethodUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;


@FoxEdgeDeviceType(value = "温湿度传感器(ST01)", manufacturer = "万图思睿")
public class ReadTemperatureAndHumidity {

    @FoxEdgeOperate(name = "读数据", polling = true, type = "encoder", timeout = 2000)
    public static String packReadInputRegister(Map<String, Object> param) {
        return (String) operateReadRegister("", param);

    }


    @FoxEdgeOperate(name = "读数据", polling = true, type = "decoder", timeout = 2000)
    public static Map<String, Object> unpackReadInputRegister(String hexString, Map<String, Object> param) {
        return (Map<String, Object>) operateReadRegister(hexString, param);

    }


    private static Object operateReadRegister(String hexString, Map<String, Object> param) {
        Integer devAddr = (Integer) param.get("devAddr");
        String modbusMode = (String) param.get("modbusMode");
        Integer regAddr = (Integer) param.get("regAddr");
        Integer regCnt = (Integer) param.get("regCnt");


        if (MethodUtils.hasEmpty(devAddr, modbusMode, regAddr, regCnt)) {
            throw new ProtocolException("输入参数不能为空:devAddr, modbusModem,regAddr,regCnt");

        }


        ModBusProtocol protocol = ModBusProtocolFactory.createProtocol(modbusMode);


        if (hexString.isEmpty()) {
            byte[] pack = protocol.packCmdReadRegisters4Map((byte) 3, param);
            return HexUtils.byteArrayToHexString(pack);

        }


        byte[] arrCmd = HexUtils.hexStringToByteArray(hexString);

        Map<String, Object> value = new HashMap<>();
        if (arrCmd != null && arrCmd.length >= 7) {
            String string = hexString.replaceAll(" ", "");
            String temperature = string.substring(6, 10);
            String humidity = string.substring(10, 14);
            int decimal = Integer.parseInt(humidity, 16);
            int decimal1 = Integer.parseInt(temperature, 16);

            if (decimal1 > 1000) {
                decimal1 = dealInverseCode(decimal1);

            }
            BigDecimal sdBig = new BigDecimal(decimal + "");
            BigDecimal wdBig = new BigDecimal(decimal1 + "");
            BigDecimal b = new BigDecimal(10);
            value.put("温度", wdBig.divide(b, 1, RoundingMode.HALF_UP));
            value.put("temperature", wdBig.divide(b, 1, RoundingMode.HALF_UP));
            value.put("humidity", sdBig.divide(b, 1, RoundingMode.HALF_UP));
            value.put("湿度", sdBig.divide(b, 1, RoundingMode.HALF_UP));

        }

        return value;

    }


    public static String hexStringSub(String hexString) {
        String string = hexString.replaceAll(" ", "");
        return string.substring(4, 10);

    }


    private static int dealInverseCode(int decimal1) {
        String binaryString = Integer.toBinaryString(decimal1);
        int targetLength = 16;

        String paddedBinaryString = String.format("%0" + targetLength + "d", Long.valueOf(Long.parseLong(binaryString)));
        StringBuilder complementString = new StringBuilder();
        for (char c : paddedBinaryString.toCharArray()) {
            if (c == '0') {
                complementString.append('1');

            } else {
                complementString.append('0');

            }

        }

        int complementNum = -(Integer.parseInt(complementString.toString(), 2) + 1);
        return complementNum;

    }

}
